package com.itany.corejava.code17_设计模式.动态代理;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

/**
 * @author 石小俊
 * @date 2023年06月02日 16:09
 */
public class LogInvocationHandler implements InvocationHandler {

    private Object target;

    public LogInvocationHandler(Object target) {
        this.target = target;
    }

    /**
     * 代理方法的具体实现,该方法代理所有的目标类中所有的方法
     * @param proxy  生成的代理对象,基本没用
     * @param method 目标方法
     * @param args   目标方法的参数列表
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("动态代理:在" + new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").format(new Date()) + "即将执行" + method.getName() + "方法,方法的参数列表为:" + Arrays.toString(args));

        // 执行目标方法
        // 参数一:从中调用的底层方法的对象。即:目标类对象
        // 参数二:目标方法的参数
        // 在此时,无法确定目标类是谁。只有当执行该方法的时候才能知道目标类是谁
        // 即:只有程序运行期间才能知道目标类是谁
        // 因此,我们可以做一个限制,限制方法调用者调用该方法时必须传递目标类进来
        // 即:实例化当前对象时使用有参构造方法创建对象,其参数即为目标类对象
        Object result = method.invoke(target, args);

        System.out.println("在" + new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").format(new Date()) + "成功执行" + method.getName() + "方法,方法返回值为:" + result);
        return result;
    }
}
